<template>
  <div class="map">
    <div class="map-container"></div>
    <div class="north-arrow"
      @click="resetNorth"
      :style="`transform: rotate(${-bearing}deg);`"></div>
  </div>
</template>

<script>
import renderPopup from '../libs/render_label'

import ThreeBoxLayer from '@/libs/threebox_layer'
import LandManager from '../libs/land_manager'
import BuildingManager from '../libs/building_manager'
import RightManager from '../libs/right_manager'
import FloorManager from '../libs/floor_manager'
import { mapState } from 'vuex'
import axios from 'axios'
mapboxgl.accessToken =
  'pk.eyJ1Ijoid2FueWFueWFuIiwiYSI6Im1uNVZnTncifQ.90XY40_yjpItUHO8HnbbpA'

export default {
  components: {
  },
  methods: {
    initMap () {
      this.map = window.map = new mapboxgl.Map({
        container: this.$el.querySelector('.map-container'),
        attributionControl: false,
        style: './data/inDoor.json',
        antialias: true
      })
      this.initTextures()
      this.map.on('load', this.styleLoaded)
    },
    styleLoaded () { // 样式加载完成后添加自定义图层、创建各种管理器、监听地图事件
      this.threeBoxLayer = new ThreeBoxLayer('3d-layer')
      this.map.addLayer(this.threeBoxLayer)
      this.landManager = new LandManager(this)
      this.buildingManager = new BuildingManager(this)
      this.rightManager = new RightManager(this)
      this.floorManager = new FloorManager(this)
      this.map.on('move', e => {
        this.bearing = this.map.getBearing()
      })
      this.map.on('click', this.mapClick)
      this.map.on('mousemove', this.mouseMove)
    },
    mapClick (e) {
      // threebox的要素查询,查到的是mesh
      let feature3D = this.threeBoxLayer.tb.queryRenderedFeatures(e.point)[0]
      // 如果查到了mesh，则进入建筑，忽略之后的宗地查询
      if (feature3D) {
        // mesh=>object3d
        let obj3d = this.threeBoxLayer.tb.findParent3DObject(feature3D)
        let userData = obj3d.userData
        if (this.mode === 'global' && userData.buildingId) {
          // 在global模式点击楼栋
          let { buildingId, floors, bearing } = userData
          if (!buildingId) {
            return
          }
          this.$store.commit('patch_building_overview', { buildingId, floors, bearing })
          this.$store.commit('patch_mode', 'building')
        } else if (this.mode === 'building' && userData.modelType == 'right') {
          // 在建筑模式点击了产权模型
          let activeFloor = Number(feature3D.object.name.slice(3, 5))
          this.$store.commit('patch_active_floor', activeFloor)
          this.$store.commit('patch_mode', 'floor')
        } else if (this.mode === 'floor' && userData.modelType == 'right') {
          // 在楼层状态点击了产权模型，如果点击的是当前层，则需要高亮，否则需要切换显示的楼层
          const clickingFloor = Number(feature3D.object.name.slice(3, 5))
          if (clickingFloor === this.activeFloor) {
            let name = feature3D.object.name
            this.$store.commit('patch_house_info', this.buildingInfo.find(item => item['模型名称'] == name))
          } else {
            this.$store.commit('patch_active_floor', clickingFloor)
          }
        }
        return
      }

      const feature = this.map.queryRenderedFeatures(e.point)[0]

      if (!feature) {
        return
      }
      // 点击的是宗地
      if (feature.layer.id.startsWith('宗地')) {
        this.$store.commit('patch_land_info', feature.properties)
      }
    },
    mouseMove(e) {

    },
    resetNorth () {
      this.map.resetNorth()
    },
    initTextures () {
      let images = ['dgqtb91147', 'dgjzb03472', 'dgjzb03351', 'pure-color']
      images.forEach(img => {
        this.map.loadImage(`./textures/${img}.jpg`, (error, image) => {
          if (error) throw error;
          if (!this.map.hasImage(img)) {
            this.map.addImage(img, image);
          }
          else {
            console.log("未加载图片");
          }
        });
      })
    },
    getBuildingInfo () {
      let { buildingId } = this.buildingOverview
      axios.get(`./properties/${buildingId}.json`).then(res => {
        this.$store.commit('patch_building_info', res.data)
      })
    },
    mouseHoverPoint () {
      if (this.flag) {
        return
      }
      this.flag = 1
      this.map.on('mouseenter', '宗地_点', this.hoverPop)
      this.map.on('mouseleave', '宗地_点', this.removePop)
    },
    closeMouseHoverPoint () {
      this.flag = 0
      this.map.off('mouseenter', '宗地_点', this.hoverPop)
      this.map.off('mouseleave', '宗地_点', this.removePop)
    },
    hoverPop (e) {
      if (this.popUp) {
        this.removePop()
        return
      }
      let pointInfo = e.features[0].properties.id
      this.popUp = new mapboxgl.Popup({
        closeButton: false
      })
      this.popUp.setHTML(renderPopup(pointInfo)).setLngLat(e.lngLat).addTo(this.map)
    },
    removePop (e) {
      this.popUp && this.popUp.remove()
      this.popUp = null
    }
  },
  mounted () {
    this.initMap()
  },
  beforeDestroy () {
    this.map.removeLayer('3d-layer')
  },
  data () {
    return {
      bearing: 0
    }
  },
  computed: {
    ...mapState({
      showBuildingsRight: state => state.showBuildingsRight,
      showLandRight: state => state.showLandRight,
      landRightOpacity: state => state.landRightOpacity,
      buildingRightOpacity: state => state.buildingRightOpacity,
      landInfo: state => state.landInfo,
      mode: state => state.mode,
      buildingOverview: state => state.buildingOverview,
      buildingInfo: state => state.buildingInfo,
      houseInfo: state => state.houseInfo,
      activeFloor: state => state.activeFloor
    })
  },
  watch: {
    landRightOpacity () {
      this.landManager.setExtrusionOpacity()
    },
    showBuildingsRight () {
      this.rightManager.updateStatus()
    },
    showLandRight () {
      if (this.showLandRight) {
        this.landManager.extrude()
      } else {
        this.landManager.flattern()
      }
    },
    landInfo () {
      if (this.landInfo) {
        this.map.setFilter('宗地_选中', ["==", "地块编号", this.landInfo['地块编号']])
        this.map.setFilter('宗地_点', ["==", "地块编号", this.landInfo['地块编号']])
        // 点击宗地后，界址点的悬浮
        this.mouseHoverPoint()
      } else {
        this.map.setFilter('宗地_选中', ["==", "地块编号", ''])
        this.map.setFilter('宗地_点', ["==", "地块编号", ''])
        // 关闭后，取消悬浮
        this.closeMouseHoverPoint()
      }
    },
    buildingRightOpacity () {
      this.rightManager.updateStatus()
    },
    mode () {
      switch (this.mode) {
        case 'global': {
          this.buildingManager.reset()
          this.rightManager.extrustOthers()
          this.rightManager.updateStatus()
          this.floorManager.removeFloors()
          break
        }
        case 'building': {
          // 重置宗地的状态
          this.landManager.reset()
          this.$store.commit('patch_active_floor', 0)
          this.buildingManager.easeToBuilding()
          this.rightManager.flatternOthers()
          this.floorManager.addFloors()
          // 请求楼栋的属性详情
          this.getBuildingInfo()
          break
        }
        case 'floor': {
          break
        }
      }
    },
    activeFloor (newFloor, oldFloor) {
      if (oldFloor) {
        this.floorManager.easeIn(oldFloor)
        this.rightManager.easeIn(oldFloor)
      }
      if (newFloor > 0) {
        this.floorManager.easeOut(newFloor)
        this.rightManager.easeOut(newFloor)
      }
      if (this.houseInfo && Number(this.houseInfo['层数']) !== newFloor) {
        this.$store.commit('patch_house_info', null)
      }
    },
    houseInfo () {
      if (this.houseInfo) {
        this.rightManager.hilightHouse()
      } else {
        this.rightManager.updateStatus()
      }
    }
  }
}
</script>

<style lang="less" scoped>
.map-container,
.map {
  position: absolute;
  width: 100%;
  height: 100%;
  text-align: left;
}

.north-arrow {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background-color: rgba(11, 46, 70, 0.8);
  background-image: url(~@/assets/north.svg);
  background-position: center;
  background-size: 30px;
  background-repeat: no-repeat;
  position: absolute;
  bottom: 40px;
  left: 40px;
  cursor: pointer;
}
</style>
